package org.abbett.eskine.dao.jpa;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.PostConstruct;
import javax.persistence.Query;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import org.abbett.eskine.dao.PageDao;
import org.abbett.eskine.entity.Page;

@Component("pageDao")
@Repository
@Transactional
public class JpaPageDao extends AbstractJpaDao<JPAPersistable<Integer>> implements PageDao {
    @Override
    public void create(Page page) {
        Object pk = page.primaryKey();
        if (pk == null) {
            pk = generatePrimaryKey();
            
            page.setId((String) pk);
        }

        em.persist(page);
    }

    @PostConstruct
    public void init() {
        // initialize the db with some initial data
    }

    /**
     * The "Create" or "Update" semantics of "CRUD"
     */
    public void createOrUpdate(Page page) {
        if (page.primaryKey() == null) {
            create(page);
            return;
        }

        em.merge(page);
    }

    /**
     * Find by Primary key
     * 
     * The "read" operation of CRUD
     */
    public Page findByPrimaryKey(String key) {
        if (key == null) {
            return null;
        }
        return em.find(JpaPage.class, key);
    }


    @Override
    public void delete(Page page) {
        em.remove(page);
    }

    @Override
    public void update(Page page) {
        em.merge(page);
    }


    /**
     * All Pages. 
        				All pages.
        			
     * 
     * The "read" operation of CRUD
     */
    public List<Page> findPages(Map<String, Object> params) {
        Query qry = em.createQuery("from JpaPage page " /* where page.field1=:param1 and page.field2=:param2 */);
        // qry.setParameter("param1", param1);
        // qry.setParameter("param2", param2);
        @SuppressWarnings("unchecked")
        List<JpaPage> pageList = qry.getResultList();

        return new ArrayList<Page>(pageList);
    }

    /**
     * Pages By User. 
                        All issues belonging to the user.
                    
     * 
     * The "read" operation of CRUD
     */
    public List<Page> findUserPages(Map<String, Object> params) {
        Query qry = em.createQuery("from JpaPage page " /* where page.field1=:param1 and page.field2=:param2 */);
        // qry.setParameter("param1", param1);
        // qry.setParameter("param2", param2);
        @SuppressWarnings("unchecked")
        List<JpaPage> pageList = qry.getResultList();

        return new ArrayList<Page>(pageList);
    }
    
    /**
     * Page. 
						A page, referenced by its identifier.
					
     * 
         * The "read" operation of CRUD
     */
    public Page getPage(Map<String, Object> params) {
        Query qry = em.createQuery("from JpaPage page " /* where page.field1=:param1 and page.field2=:param2 */);
        // qry.setParameter("param1", param1);
        // qry.setParameter("param2", param2);
        @SuppressWarnings("unchecked")
        List<JpaPage> pageList = qry.getResultList();

        if (pageList.size() == 0) {
            return null;
        }

        if (pageList.size() == 1) {
            return pageList.get(0);
        }

        throw new RuntimeException(
                "More than one Page found. Please contact the administrator.");    
    }

    @Override
    public Page newInstance() {
        return new JpaPage();
    }

    private Object generatePrimaryKey() {
        return UUID.randomUUID().toString();
    }
}// clickframes::version=1751302270::clickframes